using System.Buffers;
using System.Net;
using System.Net.Sockets;
using Nova.Net;

namespace KCP.Simple;

public class KcpClient
{
    private UdpClient _client;
    private uint _conv;
    private uint _conv_mask; //沟通conv的识别标记
    private Random _random = new ();
    private IPEndPoint serverEndPoint; //服务器地址
    private int _state; //0新创建，1已得到服务器确认

    private KcpHandler _kcpHandler;

    public KcpClient(string host, ushort port)
    {
        var addr = IPAddress.Parse(host);
        serverEndPoint = new IPEndPoint(addr, port);
        _client = new UdpClient(port+(int)(_random.NextDouble()*9999));
        _conv_mask = (uint)_random.Next();
        send_conv_msg(101, _conv);
        BeginRecv();
    }

    public void handler(KcpHandler handler)
    {
        this._kcpHandler = handler;
    }
    
    private async void BeginRecv()
    {
        var res = await _client.ReceiveAsync();
        //EndPoint = res.RemoteEndPoint;
        //kcp.Input(res.Buffer);
        Console.WriteLine("收到消息，Len="+res.Buffer.Length);
        if (res.Buffer.Length == 6)
        {
            //var action = BitConverter.ToUInt16(res.Buffer, 0);
            //_conv = BitConverter.ToUInt32(res.Buffer, 2);
            using var ds = DataStream.Allocate(res.Buffer);
            var action = ds.ReadUShort();
            var conv = ds.ReadUInt();
            Console.WriteLine($"action={action} , conv={conv}");
            switch (action)
            {
                //如果是conv消息
                case 102:
                    _conv = conv;
                    send_conv_msg(103, _conv);
                    _state = 1;
                    break;
            }
        }
        
        BeginRecv();
    }


    private async void send_conv_msg(ushort action, uint conv)
    {
        using var ds = DataStream.Allocate();
        ds.WriteUShort(action); //向客户端发送conv
        ds.WriteUInt(conv);
        _client.SendAsync(ds.ToArray(), (int)ds.Length, serverEndPoint);
    }
    
    public async void Send(string v)
    {
        var buffer = System.Text.Encoding.UTF8.GetBytes(v);
        _client.SendAsync(buffer, buffer.Length,serverEndPoint);
        
    }

}
